/**
 * @file draw.cpp
 * @author 范文宇 (2643660853@qq.com)
 * @brief 
 * @version 1.0
 * @date 2022-10-21
 * 
 * @copyright Copyright (c) 2022
 * 
 */
#include "draw.h"

using namespace std;
using namespace cv;

Draw::Draw(int point_width, int point_height)
{
    _img_height = drawparameter._img_height;
    _img_width = drawparameter._img_width;
    _point_height = drawparameter._point_height;
    _point_width = drawparameter._point_width;
    _point_size = drawparameter._point_size;
    _background_color = drawparameter._background_color;
    _line_color = drawparameter._line_color;
    _startpoint_color = drawparameter._startpoint_color;
    _endpoint_color = drawparameter._endpoint_color;
    _path_color = drawparameter._path_color;
}


cv::Mat Draw::createImg()
{
	return Mat(_img_height, _img_width, CV_8UC3, _background_color);
}


void Draw::DrawImg(cv::Mat &img, std::vector<Point2i> *obstacle, int sizeOfObstacle,
					 cv::Point2i startingPoint, cv::Point2i finishingPoint,
					 std::vector<int> *shortestPath, int sizeOfPath)
{
	DrawBackground(img);
	DrawPath(img, shortestPath, sizeOfPath);
	DrawStartingPoint(img, startingPoint);
	DrawFinishingPoint(img, finishingPoint);
	DrawObstacle(img, obstacle, sizeOfObstacle);
}

void Draw::DrawBackground(cv::Mat &img)
{
	img = Mat(_img_height, _img_width, CV_8UC3, _background_color); // 图像初始化
	for (int row = 0; row < _img_height; row += _point_size + 1)
	{
		line(img, Point(0, row), Point(_img_width, row), _line_color);
	}
	for (int col = 0; col < _img_width; col += _point_size + 1)
	{
		line(img, Point(col, 0), Point(col, _img_height), _line_color);
	}
}


void Draw::DrawObstacle(cv::Mat &img, std::vector<Point2i> *obstacle, int sizeOfObstacle)
{
	Vec3b obstacle_color(_obstacle_color[0], _obstacle_color[1], _obstacle_color[2]);
	for (int i = 0; i < sizeOfObstacle; i++)
	{
		for (int row = (*obstacle)[i].y * _point_size + (*obstacle)[i].y + 1;
			 row < ((*obstacle)[i].y + 1) * _point_size + ((*obstacle)[i].y + 1); row++)
			for (int col = (*obstacle)[i].x * _point_size + (*obstacle)[i].x + 1;
				 col < ((*obstacle)[i].x + 1) * _point_size + ((*obstacle)[i].x + 1); col++)
				img.at<Vec3b>(row, col) = obstacle_color;
	}
}


void Draw::DrawStartingPoint(cv::Mat &img, Point2i startingPoint)
{
	Vec3b startingPoint_color(_startpoint_color[0], _startpoint_color[1], _startpoint_color[2]);
	for (int row = startingPoint.y * _point_size + startingPoint.y + 1;
		 row < (startingPoint.y + 1) * _point_size + (startingPoint.y + 1); row++)
		for (int col = startingPoint.x * _point_size + startingPoint.x + 1;
			 col < (startingPoint.x + 1) * _point_size + (startingPoint.x + 1); col++)
			img.at<Vec3b>(row, col) = startingPoint_color;
}


void Draw::DrawFinishingPoint(cv::Mat &img, Point2i finishingPoint)
{
	Vec3b finishingPoint_color(_endpoint_color[0], _endpoint_color[1], _endpoint_color[2]);
	for (int row = finishingPoint.y * _point_size + finishingPoint.y + 1;
		 row < (finishingPoint.y + 1) * _point_size + (finishingPoint.y + 1); row++)
		for (int col = finishingPoint.x * _point_size + finishingPoint.x + 1;
			 col < (finishingPoint.x + 1) * _point_size + (finishingPoint.x + 1); col++)
			img.at<Vec3b>(row, col) = finishingPoint_color;
}


void Draw::DrawPath(cv::Mat &img, std::vector<int> *shortestPath, int sizeOfPath)
{
	vector<Point2f> pathPoint;
	pathPoint.reserve(sizeOfPath);
	Vec3b Path_color(_path_color[0], _path_color[1], _path_color[2]);
	for (int i = 0; i < sizeOfPath; i++)
	{
		pathPoint.push_back(Point2i((*shortestPath)[i] % _point_width,
									(*shortestPath)[i] / _point_width));
		for (int row = pathPoint[i].y * _point_size + pathPoint[i].y + 1;
			 row < (pathPoint[i].y + 1) * _point_size + (pathPoint[i].y + 1); row++)
			for (int col = pathPoint[i].x * _point_size + pathPoint[i].x + 1;
				 col < (pathPoint[i].x + 1) * _point_size + (pathPoint[i].x + 1); col++)
				img.at<Vec3b>(row, col) = Path_color;
	}
}